package com.tanhua.dubbo.server.service;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.dubbo.config.annotation.Reference;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.tobato.fastdfs.domain.conn.FdfsWebServer;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.tanhua.common.exception.BusinessException;
import com.tanhua.common.mapper.UserInfoMapper;
import com.tanhua.common.pojo.User;
import com.tanhua.common.pojo.UserInfo;
import com.tanhua.common.utils.UserThreadLocal;
import com.tanhua.common.vo.ErrorResult;
import com.tanhua.dubbo.server.api.QuanZiApi;
import com.tanhua.dubbo.server.api.VideoApi;
import com.tanhua.dubbo.server.enums.CommentPublishIdType;
import com.tanhua.dubbo.server.enums.CommentType;
import com.tanhua.dubbo.server.pojo.Video;
import com.tanhua.dubbo.server.vo.PageResult;
import com.tanhua.dubbo.server.vo.VideoVo;
import com.tanhua.oss.OssTemplate;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.List;


/**
 * Created with IntelliJ IDEA.
 *
 * @ClassName: VideoService
 * @Author:王晨晗
 * @Description:
 * @Date: 2022/01/03/14:27
 */
@Service
@Slf4j
public class VideoService {
    @Reference
    private VideoApi videoApi;

    @Autowired
    private FastFileStorageClient storageClient;
    @Autowired
    private FdfsWebServer fdfsWebServer;
    @Autowired
    private OssTemplate ossTemplate;
    @Autowired
    private UserInfoMapper userInfoMapper;

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @Reference
    private QuanZiApi quanZiApi;

    @Autowired
    private QuanZiService quanZiService;

    @Autowired
    private VideoMQService videoMQService;

    /**
     * @description 保存小视频
     * @param picFile  封面图片
     * @param videoFile  视频
     * @return
     */
    public void saveVideo(MultipartFile picFile, MultipartFile videoFile) {
        //获取用户
        User user = UserThreadLocal.get();
        //封装视频信息
        Video video = new Video();
        video.setId(ObjectId.get());        //视频id
        video.setUserId(user.getId());      //发布者id
        video.setCreated(System.currentTimeMillis());   //创建时间
        video.setSeeType(1);        //可见类型
        try {
            //上传封面
            String picUrl = ossTemplate.uploadFile(picFile);
            video.setPicUrl(picUrl);
            //上传视频
            StorePath storePath = storageClient.uploadFile(videoFile.getInputStream()
                    , videoFile.getSize()
                    , StrUtil.subAfter(videoFile.getOriginalFilename(), ".", true), null);
            //保存视频url
            video.setVideoUrl(fdfsWebServer.getWebServerUrl() + storePath.getFullPath());
            //将视频信息进行保存
            Boolean result = videoApi.saveVideo(video);
            if (!result){
                throw new BusinessException(ErrorResult.saveVideoError());
            }else {
                //发送消息
               videoMQService.videoMsg(video.getId().toHexString());
            }
        } catch (Exception e) {
            log.error("视频发布失败,video:" + video , e);
            throw new BusinessException(ErrorResult.saveVideoError());
        }
    }

    /**
     * @description 查询视频列表
     * @param page
     * @param pageSize
     * @return
     */
    public PageResult queryVideoList(Integer page, Integer pageSize) {
        //获取用户信息
        User user = UserThreadLocal.get();
        //查询视频列表
        List<Video> videoList = videoApi.queryVideoList(user.getId(), page, pageSize);

        //封装要返回的信息
        PageResult pageResult = new PageResult();
        pageResult.setPage(page);
        pageResult.setPagesize(pageSize);

        //遍历小视频的信息;
        List<VideoVo> videoVoList = new ArrayList<>();
        for (Video video : videoList) {
            //创建响应对象VideoVo
            VideoVo videoVo = new VideoVo();
            //封装信息
            videoVo.setUserId(video.getUserId());           //发布者id
            videoVo.setVideoUrl(video.getVideoUrl());       //视频保存地址
            videoVo.setCover(video.getPicUrl());            //封面保存地址
            videoVo.setId(video.getId().toHexString());     //视频id

            videoVo.setSignature("我就是我~"); //TODO 签名
            videoVo.setCommentCount(Convert.toInt(quanZiApi.queryCount(videoVo.getId() , CommentType.COMMENT))); // 评论数
            videoVo.setHasFocus(videoApi.queryIsFollow(user.getId() , videoVo.getUserId())? 1 : 0); //是否关注
            videoVo.setHasLiked(quanZiApi.queryUserIf(user.getId() , videoVo.getId(), CommentType.LIKE)? 1: 0); // 是否点赞（1是，0否）
            videoVo.setLikeCount(Convert.toInt(quanZiApi.queryCount(videoVo.getId() , CommentType.LIKE)));// 点赞数

            //查询用户信息
            LambdaQueryWrapper<UserInfo> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(UserInfo::getUserId , videoVo.getUserId());
            UserInfo userInfo = userInfoMapper.selectOne(wrapper);

            videoVo.setNickname(userInfo.getNickName());        //昵称
            videoVo.setAvatar(userInfo.getLogo());              //头像

            //添加videovo到集合中
            videoVoList.add(videoVo);
        }

        //封装集合信息
        pageResult.setItems(videoVoList);
        //返回结果
        return pageResult;
    }

    /**
     * @description 小视频点赞
     * @param videoId
     * @return
     */
    public Long likeComment(String videoId) {
        //获取用户信息
        User user = UserThreadLocal.get();
        //为小视频点赞
        Boolean flag = quanZiApi.likeOrLoveComment(user.getId(), videoId, CommentType.LIKE , CommentPublishIdType.MOVIE);
        //判断点赞状态
        if (flag){
            //发送消息
            videoMQService.likeVideoMsg(videoId);
            //返回点赞数
            return quanZiApi.queryCount(videoId , CommentType.LIKE);
        }
        throw new BusinessException(ErrorResult.likeCommentError());
    }

    /**
     * @description 小视频取消点赞
     * @param videoId
     * @return
     */
    public Long disLikeComment(String videoId) {
        //获取用户信息
        User user = UserThreadLocal.get();
        //取消点赞
        Boolean flag = quanZiApi.disLikeOrLove(user.getId(), videoId, CommentType.LIKE);
        if (flag){
            //发送消息
            videoMQService.disLikeVideoMsg(videoId);
            return quanZiApi.queryCount(videoId , CommentType.LIKE);
        }
        throw new BusinessException(ErrorResult.likeCommentError());
    }

    /**
     * @description 查询小视频评论列表
     * @param videoId   视频id
     * @param page 当前页
     * @param pageSize 每页条数
     * @return
     */
    public PageResult queryCommentsList(String videoId, Integer page, Integer pageSize) {
        return quanZiService.queryCommentList(videoId , page , pageSize);
    }

    /**
     * @description 保存评论
     * @param videoId 视频id
     * @param content 评论内容
     * @return
     */
    public Boolean saveComment(String videoId, String content) {
        //获取用户信息
        User user = UserThreadLocal.get();

        //查询是否有冻结
        String redisKey="USER_FREEZE_"+user.getId();
        String data = redisTemplate.opsForValue().get(redisKey);
        //有冻结
        if(ObjectUtil.isNotEmpty(data)){
            //判断是否是登陆冻结
            if(StringUtils.equals(data,"2")){
                throw new BusinessException(ErrorResult.commentFreezeFail());
            }
        }

        Boolean result = quanZiService.saveComments(videoId, content, CommentPublishIdType.MOVIE);//申明是小视频的评论
        if(result){
            //发送消息
            videoMQService.commentVideoMsg(videoId);
        }
        return result;
    }

    /**
     * @description 关注用户
     * @param userId
     * @return
     */
    public void saveUserFocusComments(Long userId) {
        User user = UserThreadLocal.get();
        Boolean result = videoApi.followUser(user.getId(), userId);
        if (!result){
            throw new BusinessException(ErrorResult.followUserError());
        }
    }

    /**
     * @description 取消关注
     * @param userId
     * @return
     */
    public void saveUserUnFocusComments(Long userId) {
        User user = UserThreadLocal.get();
        Boolean result = videoApi.disFollowUser(user.getId(), userId);
        if (!result){
            throw new BusinessException(ErrorResult.followUserError());
        }
    }
}
